// $Id: uuid_ptr.cpp 2 2009-09-02 08:47:42Z joseph2002 $
/*
 * Copyright 2009 Joseph Wu
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 *
 * For more information, see http://xpcomplus.sourceforge.net
 */

#include <boost/test/unit_test.hpp>
#include <xpcom/memory.hpp>
#include <xpcom/proxy/uuid_ptr.hpp>

namespace xpcom {
namespace {

const uuid s_id1 = uuid::nil;
const uuid s_id2 = { 0x64D47515, 0xADE3, 0xa5d1, { 0xAB, 0xAE, 0x3A, 0x93, 0x62, 0xC5, 0xA5, 0x51 } };
const uuid s_id3 = { 0x66666666, 0xADE3, 0xa5d1, { 0xAB, 0xAE, 0x3A, 0x93, 0x62, 0xC5, 0xA5, 0x51 } };

void do_out_impl_1(uuid** u)
{
    BOOST_CHECK(*u == 0);
    *u = 0;
}

void do_out_1(uuid& u)
{
    do_out_impl_1(proxy::uuid_ptr_out(u));
}

void do_out_impl_2(uuid** u)
{
    BOOST_CHECK(*u == 0);
    *u = ::new(mem) uuid(s_id1);
}

void do_out_2(uuid& u)
{
    do_out_impl_2(proxy::uuid_ptr_out(u));
}

void do_out_impl_3(uuid** u)
{
    BOOST_CHECK(*u == 0);
    *u = ::new(mem) uuid(s_id2);
}

void do_out_3(uuid& u)
{
    do_out_impl_3(proxy::uuid_ptr_out(u));
}

void do_inout_impl_1(uuid** u)
{
    BOOST_CHECK(**u == s_id2);
    memory::free(*u);
    *u = 0;
}

void do_inout_1(uuid& u)
{
    do_inout_impl_1(proxy::uuid_ptr_inout(u));
}

void do_inout_impl_2(uuid** u)
{
    BOOST_CHECK(**u == s_id2);
    **u = s_id3;
}

void do_inout_2(uuid& u)
{
    do_inout_impl_2(proxy::uuid_ptr_inout(u));
}

void do_inout_impl_3(uuid** u)
{
    BOOST_CHECK(*u == 0);
    *u = ::new(mem) uuid(s_id1);
}

void do_inout_3(uuid& u)
{
    do_inout_impl_3(proxy::uuid_ptr_inout(u));
}

}
}

BOOST_AUTO_TEST_CASE(test_uuid_ptr_in)
{
    using namespace xpcom;

    uuid id1 = s_id1;
    uuid id2 = s_id2;

    BOOST_CHECK(proxy::uuid_ptr_in(id1) == 0);
    BOOST_CHECK(proxy::uuid_ptr_in(uuid::nil) == 0);
    BOOST_CHECK(proxy::uuid_ptr_in(id2) == &id2);
    BOOST_CHECK(*proxy::uuid_ptr_in(id2) == id2);
}

BOOST_AUTO_TEST_CASE(test_uuid_ptr_out)
{
    using namespace xpcom;

    uuid id;
    do_out_1(id);
    BOOST_CHECK(id == uuid::nil);

    do_out_2(id);
    BOOST_CHECK(id == s_id1);

    do_out_3(id);
    BOOST_CHECK(id == s_id2);
}

BOOST_AUTO_TEST_CASE(test_uuid_ptr_inout)
{
    using namespace xpcom;

    uuid id;

    id = s_id2;
    do_inout_1(id);
    BOOST_CHECK(id == uuid::nil);

    id = s_id2;
    do_inout_2(id);
    BOOST_CHECK(id == s_id3);

    id = uuid::nil;
    do_inout_3(id);
    BOOST_CHECK(id == s_id1);
}
